package com.xique.park.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xique.common.core.utils.DateUtils;
import com.xique.common.core.utils.StringUtils;
import com.xique.park.bean.domain.ParkOn;
import com.xique.park.bean.domain.ParkingOrderOn;
import com.xique.park.bean.domain.PayOrder;
import com.xique.park.constant.CommandStatus;
import com.xique.park.constant.DictConstant;
import com.xique.park.constant.RedisConstants;
import com.xique.park.constant.message.LaneDtConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 *
 * @author Administrator
 * description:
 * path: park2020-com.jzy.handler-RedisHandler
 * date: 2020/7/9 18:43
 */
@Component
@Slf4j
public class RedisHandler {

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 保存某个设备发送某个cmd命令的发送内容
     *
     * @param devCode 设备编号
     * @param cmd     命令
     * @param obj     发送内容
     */
    public void saveDevCmdSendMsg(String devCode, Integer cmd, JSONObject obj) {
        if (StringUtils.isNotEmpty(devCode)) {
            JSONObject finalObj = new JSONObject();
            finalObj.put("data", obj);
            finalObj.put("time", DateUtils.getTime());
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_STATUS_PREFIX + devCode + ":SENDCMD:" + cmd, finalObj);
        }
    }

    /**
     * 获取某个设备发送某个cmd命令的发送内容
     *
     * @param devCode 设备编号
     * @param cmd     命令
     * @return 发送内容
     */
    public JSONObject getDevCmdSendMsg(String devCode, Integer cmd) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_STATUS_PREFIX + devCode + ":SENDCMD:" + cmd);
        if (null != obj) {
            return JSONObject.parseObject(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 保存某个设备发送某个cmd命令的应答内容
     *
     * @param devCode 设备编号
     * @param cmd     命令
     * @param obj     应答内容
     */
    public void saveDevCmdAckMsg(String devCode, Integer cmd, JSONObject obj) {
        if (StringUtils.isNotEmpty(devCode)) {
            JSONObject finalObj = new JSONObject();
            finalObj.put("data", obj);
            finalObj.put("time", DateUtils.getTime());
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_STATUS_PREFIX + devCode + ":ACKCMD:" + cmd, finalObj);
        }
    }

    /**
     * 获取某个设备发送某个cmd命令的应答内容
     *
     * @param devCode 设备编号
     * @param cmd     命令
     * @return 应答内容
     */
    public JSONObject getDevCmdAckMsg(String devCode, Integer cmd) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_STATUS_PREFIX + devCode + ":ACKCMD:" + cmd);
        if (null != obj) {
            return JSONObject.parseObject(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 保存命令下发以后，设备返回的应答消息
     * 消息保存时长1分钟
     *
     * @param devCode 设备编号
     * @param cmd     (cmd为整形)
     * @param msgId   消息id
     */
    public void saveAckMsg(String devCode, Integer cmd, String msgId, JSONObject obj) {
        if (StringUtils.isNotEmpty(msgId) && StringUtils.isNotEmpty(devCode)) {
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_RESP_PREFIX + cmd + ":" + devCode + ":" + msgId, obj.toString(), 60);
        }
    }

    /**
     * 门禁-保存命令下发以后，设备返回的应答消息
     *
     * @param devCode 设备编号
     * @param cmd     (cmd为字符串)
     * @param msgId   msgId
     * @param obj     应答消息
     */
    public void saveAckMsg(String devCode, String cmd, String msgId, JSONObject obj) {
        if (StringUtils.isNotEmpty(msgId) && StringUtils.isNotEmpty(devCode)) {
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_RESP_PREFIX + cmd + ":" + devCode + ":" + msgId, obj.toString(), 60);
        }
    }

    /**
     * 获取下发命令的应答信息
     *
     * @param devCode 设备编号
     * @param cmd     (cmd为整形)
     * @param msgId   消息id
     * @return 应答信息
     */
    public JSONObject getAckMsg(String devCode, Integer cmd, long msgId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_RESP_PREFIX + cmd + ":" + devCode + ":" + msgId);
        if (null != obj) {
            return JSONObject.parseObject(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 获取下发命令的应答信息
     *
     * @param devCode 设备编号
     * @param cmd     (cmd为字符串)
     * @param msgId   消息id
     * @return 应答信息
     */
    public JSONObject getAckMsg(String devCode, String cmd, long msgId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_RESP_PREFIX + cmd + ":" + devCode + ":" + msgId);
        if (null != obj) {
            return JSONObject.parseObject(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 保存异步命令下发以后的消息内容(单个设备，单条记录)
     * 消息保存时长为7天
     *
     * @param devCode 设备编号
     * @param data    消息内容
     */
    public void saveAsyncCommandData(String className, String devCode, Long recId, JSONObject data) {
        if (StringUtils.isNotEmpty(devCode)) {
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_DATA_PREFIX + devCode + ":" + className + ":" + recId, data.toString(), 604800);
        }
    }

    /**
     * 获取异步命令下发以后的消息内容（单个设备，单条记录）
     *
     * @param devCode 设备编号
     * @return 消息内容
     */
    public JSONObject getAsyncCommandData(String className, String devCode, Long recId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_DATA_PREFIX + devCode + ":" + className + ":" + recId);
        if (null != obj) {
            return JSONObject.parseObject(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 保存异步命令下发以后的消息内容（单个设备）
     *
     * @param devCode 设备编号
     * @param data    消息内容
     */
    public void saveAsyncCommandData(String className, String devCode, String msgId, JSONObject data) {
        redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_DATA_PREFIX + devCode + ":" + className + ":" + msgId, data.toString(), 604800L);
    }

    /**
     * 获取异步命令下发以后的消息内容（单个设备）
     *
     * @param devCode 设备编号
     * @return 消息内容
     */
    public JSONObject getAsyncCommandData(String className, String devCode, String msgId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_DATA_PREFIX + devCode + ":" + className + ":" + msgId);
        if (null != obj) {
            return JSONObject.parseObject(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 删除异步命令下发以后的消息内容
     *
     * @param devCode 设备编号
     */
    public void delAsyncCommandData(String className, String devCode, String msgId) {
        if (StringUtils.isNotEmpty(devCode)) {
            redisUtil.del(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_DATA_PREFIX + devCode + ":" + className + ":" + msgId);
        }
    }

    /**
     * 批量保存异步命令下发的状态
     * 永久保存
     *
     * @param devCode   设备编号
     * @param recIdList /
     * @param status    命令下发的状态
     */
    public void saveBatchAsyncCommandStatus(String className, String devCode, List<Long> recIdList, String status) {
        if (!CollectionUtils.isEmpty(recIdList)) {
            List<String> keys = new ArrayList<>(recIdList.size());
            JSONObject jsonObject = new JSONObject(2);
            jsonObject.put("device_code", devCode);
            jsonObject.put("status", status);
            jsonObject.put("time", DateUtils.getTime());
            for (Long recId : recIdList) {
                keys.add(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_STATUS_PREFIX + devCode + ":" + className + ":" + recId);
            }
            redisUtil.batchInsert(keys, jsonObject.toString());
        }
    }

    /**
     * 获取单个设备和单条记录的命令下发的状态
     *
     * @param devCode 设备编号
     * @param recId   /
     * @return 命令下发的状态
     */
    public JSONObject getAsyncCommandStatus(String className, String devCode, Long recId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_COMMAND_STATUS_PREFIX + devCode + ":" + className + ":" + recId);
        if (null != obj) {
            return JSONObject.parseObject(JSON.toJSONString(obj));
        } else {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("device_code", devCode);
            jsonObject.put("status", CommandStatus.UNKNOWN);
            return jsonObject;
        }
    }

    /**
     * 批量获取多条记录的多个设备的命令下发状态
     * 1、根据列表拼接key；
     * 2、根据key在redis中批量查询
     *
     * @param className   className
     * @param devCodeList 设备编号
     * @param recIdList   recIdList
     * @return 命令下发状态
     */
    public JSONObject getBatchAsyncCommandStatus(String className, List<String> devCodeList, List<Long> recIdList) {
        Map<String, Object> map = new HashMap<>(16);
        if (!CollectionUtils.isEmpty(devCodeList) && !CollectionUtils.isEmpty(recIdList)) {
            for (Long recId : recIdList) {
                List<Object> list = new ArrayList<>(devCodeList.size());
                for (String code : devCodeList) {
                    JSONObject obj = getAsyncCommandStatus(className, code, recId);
                    list.add(obj);
                }
                map.put(String.valueOf(recId), JSON.toJSONString(list));
            }
        }
        return JSONObject.parseObject(JSON.toJSONString(map));
    }

    /**
     * 抓拍图片以后，将设备上传的图片保存以后的url保存，供前端获取结果
     *
     * @param devCode 设备编号
     * @param msgId   消息id
     * @param picUrl  图片url
     */
    public void saveTrigPicUrl(String devCode, Long msgId, String picUrl) {
        if (StringUtils.isNotEmpty(devCode) && null != msgId) {
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PIC_CODE_MSGID_PREFIX + devCode + ":" + msgId, picUrl, 60);
        }
    }

    public String getTrigPicUrl(String devCode, Long msgId) {
        String picUrl = (String) redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PIC_CODE_MSGID_PREFIX + devCode + ":" + msgId);
        if (StringUtils.isNotEmpty(picUrl)) {
            return picUrl;
        } else {
            return null;
        }
    }

    /**
     * 保存设备状态到redis
     *
     * @param devCode 设备编号
     * @param obj     设备状态
     * @return 保存结果
     */
    public boolean saveDeviceStatus(String devCode, JSONObject obj) {
        return redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_DEVICE_STATUS_PREFIX + devCode, obj.toString());
    }

    /**
     * 获取单个设备的在线状态
     *
     * @param devCode 设备编号
     * @return 设备的在线状态
     */
    public JSONObject getDeviceStatus(String devCode) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_DEVICE_STATUS_PREFIX + devCode);
        // 不为空，则直接返回
        if (null != obj) {
            return JSONObject.parseObject(obj.toString());
        } else {
            // 如果为空，则返回设备不在线
            JSONObject object = new JSONObject();
            object.put("code", devCode);
            object.put("status", DictConstant.DEVICE_STATUS_OFFLINE);
            object.put("createTIme", DateUtils.getTime());
            return object;
        }
    }

    /**
     * 批量获取多个设备的在线状态
     *
     * @param devCodes 设备编号
     * @return 设备的在线状态
     */
    public JSONArray getDevicesStatus(List<String> devCodes) {
        JSONArray array = new JSONArray(devCodes.size());
        for (String code : devCodes) {
            array.add(getDeviceStatus(code));
        }
        return array;
    }

    /**
     * 批量获取多个通道的地感状态和通道闸状态
     *
     * @param laneIds 通道ID
     * @return 通道的地感状态和通道闸状态
     */
    public JSONArray getLanesSense(List<Integer> laneIds) {
        JSONArray array = new JSONArray(laneIds.size());
        for (Integer laneId : laneIds) {
            array.add(getLaneSense(laneId));
        }
        return array;
    }

    /**
     * 保存通道处理的车牌信息
     *
     * @param laneId     通道id
     * @param plate      车牌
     * @param createTime 记录产生时间（s）
     * @return 保存结果
     */
    public boolean saveLanePlate(Long laneId, String plate, Long createTime) {
        JSONObject object = new JSONObject();
        object.put("laneId", laneId);
        object.put("plate", plate);
        object.put("createTime", createTime);
        return redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_LANE_PLATE_PREFIX + laneId, object.toString());
    }

    /**
     * 获取通道最近处理过的车牌信息
     *
     * @param laneId 通道id
     * @return 通道最近处理过的车牌信息
     */
    public JSONObject getLanePlate(Long laneId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_LANE_PLATE_PREFIX + laneId);
        if (null != obj) {
            return JSONObject.parseObject(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 保存通道的最新地感状态
     *
     * @param laneId     通道id
     * @param sense      地感状态
     * @param gateState  通道道闸状态
     * @param createTime 创建时间
     * @return 保存结果
     */
    public boolean saveLaneSense(Long laneId, Integer sense, Integer gateState, Long createTime) {
        JSONObject object = new JSONObject();
        object.put("laneId", laneId);
        object.put(LaneDtConstants.IS_SENSE, sense);
        object.put(LaneDtConstants.IS_GATE_STATE, gateState);
        object.put("createTime", createTime);
        return redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_LANE_SENSE_PREFIX + laneId, object.toString());
    }

    /**
     * 获取通道的最新地感状态
     *
     * @param laneId 通道ID
     * @return 通道的最新地感状态
     */
    public JSONObject getLaneSense(Integer laneId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_LANE_SENSE_PREFIX + laneId);
        if (null != obj) {
            return JSONObject.parseObject(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * pYun支付通知结果处理保存，用于去重
     *
     * @param plate        车牌
     * @param parkId       车场ID
     * @param parkingOrder 订单信息
     */
    public void savePyunPaymentResult(String plate, Long parkId, String parkingOrder) {
        JSONObject object = new JSONObject();
        object.put("plate", plate);
        redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PAYMENT_UUID_ORDER_PREFIX + parkId + ":" + parkingOrder, object.toString(), 60 * 60 * 24);
    }

    /**
     * 获取pYun支付通知结果
     *
     * @param parkId       车场ID
     * @param parkingOrder 订单信息
     * @return pYun支付通知结果
     */
    public JSONObject getPyunPaymentResult(Long parkId, String parkingOrder) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PAYMENT_UUID_ORDER_PREFIX + parkId + ":" + parkingOrder);
        if (null != obj) {
            return JSONObject.parseObject(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 保存更新车场的剩余车位数
     * 1、车场车位修改的时候
     * 2、在场车辆表有变化的时候
     *
     * @param parkId       车场ID
     * @param remainSpaces 剩余车位数（由总车位-在场车辆数计算得出）
     */
    public void updateRemainSpaces(Long parkId, Long remainSpaces) {
        if (null != parkId && null != remainSpaces) {
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_REMAIN_SPACES_PREFIX + parkId, remainSpaces);
        }
    }

    /**
     * 删除车场的在场车位数
     *
     * @param parkId 车场ID
     */
    public void delRemainSpaces(Long parkId) {
        redisUtil.del(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_REMAIN_SPACES_PREFIX + parkId);
    }

    /**
     * 获取车场的剩余车位数
     *
     * @param parkId 车场ID
     * @return 车场的剩余车位数
     */
    public Long getRemainSpaces(Long parkId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_REMAIN_SPACES_PREFIX + parkId);
        if (null != obj) {
            return Long.parseLong(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 获取车库的剩余车位数
     *
     * @param parkId   车场ID
     * @param garageId 车库ID
     * @return 车库的剩余车位数
     */
    public Long getGarageRemainSpaces(Long parkId, Long garageId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_REMAIN_SPACES_PREFIX + parkId + ":" + garageId);
        if (null != obj) {
            return Long.parseLong(obj.toString());
        } else {
            return null;
        }
    }


    /**
     * 保存更新车场的总车位数
     *
     * @param parkId      车场ID
     * @param totalSpaces 总车位数
     */
    public void updateTotalSpaces(Long parkId, Long totalSpaces) {
        if (null != parkId && null != totalSpaces) {
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_TOTAL_SPACES_PREFIX + parkId, totalSpaces);
        }
    }

    /**
     * 删除更新车场的总车位数
     *
     * @param parkId 车场ID
     */
    public void delTotalSpaces(Long parkId) {
        redisUtil.del(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_TOTAL_SPACES_PREFIX + parkId);
    }

    /**
     * 获取车场总车位数
     *
     * @param parkId 车场ID
     * @return 车场总车位数
     */
    public Long getTotalSpaces(Long parkId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_TOTAL_SPACES_PREFIX + parkId);
        if (null != obj) {
            return Long.parseLong(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 保存更新车场的在场车辆数
     *
     * @param parkId   车场ID
     * @param onCarCnt 车场的在场车辆数
     */
    public void updateOnCarCnt(Long parkId, Long onCarCnt) {
        if (null != parkId && null != onCarCnt) {
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_ON_CARCNT_PREFIX + parkId, onCarCnt);
        }
    }

    /**
     * 保存更新车库的在场车辆数
     *
     * @param parkId   车场ID
     * @param garageId 车库ID
     * @param onCarCnt 车库的在场车辆数
     */
    public void updateGarageOnCarCnt(Long parkId, Long garageId, Long onCarCnt) {
        if (null != parkId && null != garageId && null != onCarCnt) {
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_ON_CARCNT_PREFIX + parkId + ":" + garageId, onCarCnt);
        }
    }

    /**
     * 删除车场在场车辆数
     *
     * @param parkId 车场ID
     */
    public void delOnCarCnt(Long parkId) {
        redisUtil.del(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_ON_CARCNT_PREFIX + parkId);
    }

    /**
     * 删除车库的在场车辆数
     *
     * @param parkId   车场ID
     * @param garageId 车库ID
     */
    public void delGarageOnCarCnt(Long parkId, Long garageId) {
        redisUtil.del(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_ON_CARCNT_PREFIX + parkId + ":" + garageId);
    }

    /**
     * 获取车场的在场车辆数
     *
     * @param parkId 车场ID
     * @return 车场的在场车辆数
     */
    public Long getOnCarCnt(Long parkId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_ON_CARCNT_PREFIX + parkId);
        if (null != obj) {
            return Long.parseLong(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 获取某车库的在场车辆数
     *
     * @param parkId   车场ID
     * @param garageId 车库ID
     * @return 某车库的在场车辆数
     */
    public Long getGarageOnCarCount(Long parkId, Long garageId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARK_ON_CARCNT_PREFIX + parkId + ":" + garageId);
        if (null != obj) {
            return Long.parseLong(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 保存某车辆在某车场的在场记录
     *
     * @param parkId 车场ID
     * @param plate  车库ID
     * @param parkOn 某车辆在某车场的在场记录
     */
    public void saveParkOnByPidPlate(Long parkId, String plate, ParkOn parkOn) {
        if (null != parkId && null != plate && null != parkOn) {
            String jsonStr = JSONObject.toJSONString(parkOn);
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARKON_PARKID_PLATE_PREFIX + parkId + ":" + plate, jsonStr);
        }
    }

    /**
     * 获取某车辆在某车场的在场记录
     *
     * @param parkId 车场ID
     * @param plate  车牌
     * @return 车辆在某车场的在场记录
     */
    public ParkOn getParkOnByPidPlate(Long parkId, String plate) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARKON_PARKID_PLATE_PREFIX + parkId + ":" + plate);
        if (null != obj) {
            return JSON.parseObject(obj.toString(), ParkOn.class);
        } else {
            return null;
        }
    }

    /**
     * 删除某车辆的在场记录
     *
     * @param parkId 车场ID
     * @param plate  车牌
     */
    public void delParkOnByPidPlate(Long parkId, String plate) {
        redisUtil.del(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARK_ON_PREFIX + RedisConstants.REDIS_PARKON_PARKID_PLATE_PREFIX + parkId + ":" + plate);
    }

    /**
     * 保存停车订单流水
     *
     * @param parkId         车场ID
     * @param plate          车牌
     * @param parkingOrderOn 停车订单流水
     */
    public void saveParkingOrder(Long parkId, String plate, ParkingOrderOn parkingOrderOn) {
        if (null != parkId && null != plate && null != parkingOrderOn) {
            String jsonStr = JSONObject.toJSONString(parkingOrderOn);
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARKINGORDER_PREFIX + RedisConstants.REDIS_PARKON_PARKID_PLATE_PREFIX + parkId + ":" + plate, jsonStr);
        }
    }

    /**
     * 保存停车流水订单 -- 增加车库id
     *
     * @param parkId         车场id
     * @param garageId       车库id
     * @param plate          车牌号
     * @param parkingOrderOn 停车订单流水
     */
    public void saveParkingOrder(Long parkId, Long garageId, String plate, ParkingOrderOn parkingOrderOn) {
        if (null != parkId && null != garageId && null != plate && null != parkingOrderOn) {
            String jsonStr = JSONObject.toJSONString(parkingOrderOn);
            redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARKINGORDER_PREFIX + RedisConstants.REDIS_PARKON_PARKID_PLATE_PREFIX + parkId + ":" + garageId + ":" + plate, jsonStr);
        }
    }

    /**
     * 获取停车订单流水
     *
     * @param parkId 车场id
     * @param plate  车牌号
     * @return 停车订单流水
     */
    public ParkingOrderOn getParkingOrderByPidPlate(Long parkId, String plate) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARKINGORDER_PREFIX + RedisConstants.REDIS_PARKON_PARKID_PLATE_PREFIX + parkId + ":" + plate);
        if (null != obj) {
            return JSON.parseObject(obj.toString(), ParkingOrderOn.class);
        } else {
            return null;
        }
    }

    /**
     * 获取停车流水订单 -- 增加车库id
     *
     * @param parkId   车场id
     * @param garageId 车库id
     * @param plate    车牌号
     * @return 停车流水订单
     */
    public ParkingOrderOn getParkingOrder(Long parkId, Long garageId, String plate) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARKINGORDER_PREFIX + RedisConstants.REDIS_PARKON_PARKID_PLATE_PREFIX + parkId + ":" + garageId + ":" + plate);
        if (null != obj) {
            return JSON.parseObject(obj.toString(), ParkingOrderOn.class);
        } else {
            return null;
        }
    }

    /**
     * 删除停车订单流水
     *
     * @param parkId 车场id
     * @param plate  车牌号
     */
    public void delParkingOrderByPidPlate(Long parkId, String plate) {
        redisUtil.del(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARKINGORDER_PREFIX + RedisConstants.REDIS_PARKON_PARKID_PLATE_PREFIX + parkId + ":" + plate);
    }

    /**
     * 通过车场id，车库id，车牌号删除停车订单
     *
     * @param parkId   车场id
     * @param garageId 车库id
     * @param plate    车牌号
     */
    public void delParkingOrder(Long parkId, Long garageId, String plate) {
        redisUtil.del(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PARKINGORDER_PREFIX + RedisConstants.REDIS_PARKON_PARKID_PLATE_PREFIX + parkId + ":" + garageId + ":" + plate);
    }

    /**
     * 保存通道处理的停车订单信息
     *
     * @param laneId         通道id
     * @param parkingOrderOn 当前停车订单
     * @param createTime     记录产生时间（s）
     * @return 保存结果
     */
    public boolean saveLaneParkingOrder(Long laneId, ParkingOrderOn parkingOrderOn, Long createTime) {
        JSONObject object = new JSONObject();
        object.put("laneId", laneId);
        object.put("ParkingOrder", parkingOrderOn);
        object.put("createTime", createTime);
        return redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_LANE_PARKINGORDER_PREFIX + laneId, object.toString());
    }

    /**
     * 获取通道最近处理过的停车订单信息
     *
     * @param laneId 通道ID
     * @return 通道最近处理过的停车订单信息
     */
    public JSONObject getLaneParkingOrder(Long laneId) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_LANE_PARKINGORDER_PREFIX + laneId);
        if (null != obj) {
            return JSONObject.parseObject(obj.toString());
        } else {
            return null;
        }
    }

    /**
     * 删除通道最近处理过的停车订单信息
     *
     * @param laneId 通道ID
     */
    public void delLaneParkingOrder(Long laneId) {
        redisUtil.del(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_LANE_PARKINGORDER_PREFIX + laneId);
    }

    /**
     * 保存最新的一条
     *
     * @param parkId        车场ID
     * @param parkingSerial 停车流水号
     * @param payOrder      支付信息
     */
    public boolean savePayOrderByPkSerial(Long parkId, String parkingSerial, PayOrder payOrder) {
        JSONObject object = new JSONObject();
        object.put("parkingSerial", parkingSerial);
        object.put("PayOrder", payOrder);
        object.put("createTime", payOrder.getCreateTime());
        return redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PAYORDER_PREFIX + parkId + ":" + parkingSerial, object.toString());
    }

    /**
     * 获取某个停车订单最近的支付订单
     *
     * @param parkId        车场ID
     * @param parkingSerial 停车流水号
     * @return 某个停车订单最近的支付订单
     */
    public PayOrder getPayOrderByPkSerial(Long parkId, String parkingSerial) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PAYORDER_PREFIX + parkId + ":" + parkingSerial);
        if (null != obj) {
            return JSON.parseObject(obj.toString(), PayOrder.class);
        } else {
            return null;
        }
    }

    /**
     * 删除某个订单最近的支付订单
     *
     * @param parkId        车场ID
     * @param parkingSerial 停车流水号
     */
    public void delPayOrderByPkSerial(Long parkId, String parkingSerial) {
        redisUtil.del(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_PAYORDER_PREFIX + parkId + ":" + parkingSerial);
    }

    /**
     * 保存内场通道进出场记录
     *
     * @param parkId            车场ID
     * @param laneId            通道ID
     * @param insideInOutRecord insideInOutRecord
     * @return 保存结果
     */
    public boolean saveInsideInOutRecord(Long parkId, Long laneId, String plate, String insideInOutRecord) {
        return redisUtil.set(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_LANE_INSIDEINOUT_PREFIX + parkId + ":" + laneId + ":" + plate, insideInOutRecord);
    }

    /**
     * 获取内场通道进出场记录
     *
     * @param parkId 车场ID
     * @param laneId 通道ID
     * @return 内场通道进出场记录
     */
    public JSONObject getInsideInOutRecord(Long parkId, Long laneId, String plate) {
        Object obj = redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_LANE_INSIDEINOUT_PREFIX + parkId + ":" + laneId + ":" + plate);
        if (null != obj) {
            return JSON.parseObject(obj.toString(), JSONObject.class);
        } else {
            return null;
        }
    }
}
